#define _GNU_SOURCE
#include "fastxml.h"

// 内部函数声明
static xml_node_t* parse_element(const char **xml, xml_node_t *parent);
static xml_attribute_t* parse_attributes(const char **xml);
static char* parse_tag_name(const char **xml);
static char* parse_content(const char **xml, const char *end_tag);
static void skip_whitespace(const char **xml);
static int match_string(const char **xml, const char *str);

// 解析XML文件
xml_document_t* xml_parse_file(const char *filename) {
    if (!filename) return NULL;
    
    FILE *file = fopen(filename, "r");
    if (!file) {
        printf("Error: Cannot open file %s\n", filename);
        return NULL;
    }
    
    // 获取文件大小
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    // 读取文件内容
    char *content = malloc(file_size + 1);
    if (!content) {
        fclose(file);
        return NULL;
    }
    
    fread(content, 1, file_size, file);
    content[file_size] = '\0';
    fclose(file);
    
    // 解析XML字符串
    xml_document_t *doc = xml_parse_string(content);
    free(content);
    
    return doc;
}

// 解析XML字符串
xml_document_t* xml_parse_string(const char *xml_string) {
    if (!xml_string) return NULL;
    
    xml_document_t *doc = malloc(sizeof(xml_document_t));
    if (!doc) return NULL;
    
    doc->root = NULL;
    doc->version = NULL;
    doc->encoding = NULL;
    
    const char *xml = xml_string;
    skip_whitespace(&xml);
    
    // 检查XML声明
    if (match_string(&xml, "<?xml")) {
        while (*xml && *xml != '>') xml++;
        if (*xml == '>') xml++;
        skip_whitespace(&xml);
    }
    
    // 解析根元素
    if (*xml == '<' && *(xml + 1) != '/') {
        doc->root = parse_element(&xml, NULL);
    }
    
    return doc;
}

// 解析元素
static xml_node_t* parse_element(const char **xml, xml_node_t *parent) {
    if (!xml || !*xml || **xml != '<') return NULL;
    
    (*xml)++; // 跳过 '<'
    
    // 解析标签名
    char *tag_name = parse_tag_name(xml);
    if (!tag_name) return NULL;
    
    xml_node_t *node = xml_create_node(XML_NODE_ELEMENT, tag_name, NULL);
    if (!node) {
        free(tag_name);
        return NULL;
    }
    
    node->parent = parent;
    
    // 解析属性
    skip_whitespace(xml);
    if (**xml != '>' && **xml != '/') {
        node->attributes = parse_attributes(xml);
    }
    
    skip_whitespace(xml);
    
    // 检查自闭合标签
    if (**xml == '/' && *(*xml + 1) == '>') {
        *xml += 2;
        free(tag_name);
        return node;
    }
    
    if (**xml == '>') {
        (*xml)++;
    } else {
        xml_free_node(node);
        free(tag_name);
        return NULL;
    }
    
    // 解析子元素和内容
    const char *content_start = *xml;
    xml_node_t *last_child = NULL;
    
    while (**xml) {
        skip_whitespace(xml);
        
        if (**xml == '<') {
            if (*(*xml + 1) == '/') {
                // 结束标签
                *xml += 2;
                char *end_tag = parse_tag_name(xml);
                if (end_tag && tag_name && strcmp(end_tag, tag_name) == 0) {
                    skip_whitespace(xml);
                    if (**xml == '>') (*xml)++;
                    free(end_tag);
                    break;
                }
                if (end_tag) free(end_tag);
                break;
            } else if (*(*xml + 1) == '!') {
                // 注释或CDATA
                if (strncmp(*xml, "<!--", 4) == 0) {
                    *xml += 4;
                    const char *comment_start = *xml;
                    while (**xml && strncmp(*xml, "-->", 3) != 0) (*xml)++;
                    if (**xml) {
                        int comment_len = *xml - comment_start;
                        char *comment = malloc(comment_len + 1);
                        if (comment) {
                            strncpy(comment, comment_start, comment_len);
                            comment[comment_len] = '\0';
                            
                            xml_node_t *comment_node = xml_create_node(XML_NODE_COMMENT, NULL, comment);
                            if (comment_node) {
                                xml_add_child(node, comment_node);
                            }
                            free(comment);
                        }
                        *xml += 3;
                    }
                }
            } else {
                // 子元素
                xml_node_t *child = parse_element(xml, node);
                if (child) {
                    xml_add_child(node, child);
                }
            }
        } else {
            // 文本内容
            const char *text_start = *xml;
            while (**xml && **xml != '<') (*xml)++;
            
            if (*xml > text_start) {
                int text_len = *xml - text_start;
                char *text = malloc(text_len + 1);
                if (text) {
                    strncpy(text, text_start, text_len);
                    text[text_len] = '\0';
                    
                    char *trimmed = xml_trim_whitespace(text);
                    if (trimmed && strlen(trimmed) > 0) {
                        if (!node->content) {
                            node->content = strdup(trimmed);
                        }
                    }
                    free(text);
                }
            }
        }
    }
    
    free(tag_name);
    return node;
}

// 解析属性
static xml_attribute_t* parse_attributes(const char **xml) {
    xml_attribute_t *first_attr = NULL;
    xml_attribute_t *last_attr = NULL;
    
    while (**xml && **xml != '>' && **xml != '/') {
        skip_whitespace(xml);
        
        if (**xml == '>' || **xml == '/') break;
        
        // 解析属性名
        const char *name_start = *xml;
        while (**xml && **xml != '=' && !isspace(**xml)) (*xml)++;
        
        if (*xml == name_start) break;
        
        int name_len = *xml - name_start;
        char *attr_name = malloc(name_len + 1);
        strncpy(attr_name, name_start, name_len);
        attr_name[name_len] = '\0';
        
        skip_whitespace(xml);
        
        if (**xml != '=') {
            free(attr_name);
            break;
        }
        
        (*xml)++; // 跳过 '='
        skip_whitespace(xml);
        
        // 解析属性值
        char quote = **xml;
        if (quote != '"' && quote != '\'') {
            free(attr_name);
            break;
        }
        
        (*xml)++; // 跳过引号
        const char *value_start = *xml;
        while (**xml && **xml != quote) (*xml)++;
        
        if (**xml != quote) {
            free(attr_name);
            break;
        }
        
        int value_len = *xml - value_start;
        char *attr_value = malloc(value_len + 1);
        strncpy(attr_value, value_start, value_len);
        attr_value[value_len] = '\0';
        
        (*xml)++; // 跳过结束引号
        
        // 创建属性
        xml_attribute_t *attr = xml_create_attribute(attr_name, attr_value);
        if (attr) {
            if (!first_attr) {
                first_attr = attr;
                last_attr = attr;
            } else {
                last_attr->next = attr;
                last_attr = attr;
            }
        }
        
        free(attr_name);
        free(attr_value);
        
        skip_whitespace(xml);
    }
    
    return first_attr;
}

// 解析标签名
static char* parse_tag_name(const char **xml) {
    const char *start = *xml;
    
    while (**xml && **xml != '>' && **xml != '/' && !isspace(**xml)) {
        (*xml)++;
    }
    
    if (*xml == start) return NULL;
    
    int len = *xml - start;
    char *name = malloc(len + 1);
    strncpy(name, start, len);
    name[len] = '\0';
    
    return name;
}

// 跳过空白字符
static void skip_whitespace(const char **xml) {
    while (**xml && isspace(**xml)) {
        (*xml)++;
    }
}

// 匹配字符串
static int match_string(const char **xml, const char *str) {
    int len = strlen(str);
    if (strncmp(*xml, str, len) == 0) {
        *xml += len;
        return 1;
    }
    return 0;
}

// 创建XML节点
xml_node_t* xml_create_node(xml_node_type_t type, const char *name, const char *content) {
    printf("Debug: xml_create_node 被调用，名称: %s\n", name ? name : "NULL");
    
    xml_node_t *node = malloc(sizeof(xml_node_t));
    if (!node) {
        printf("Debug: xml_create_node - 内存分配失败\n");
        return NULL;
    }
    
    printf("Debug: xml_create_node - 节点内存分配成功\n");
    
    node->type = type;
    node->name = name ? strdup(name) : NULL;
    node->content = content ? strdup(content) : NULL;
    node->attributes = NULL;
    node->parent = NULL;
    node->children = NULL;
    node->next = NULL;
    
    printf("Debug: xml_create_node - 节点初始化完成，名称: %s\n", node->name ? node->name : "NULL");
    
    return node;
}

// 创建XML属性
xml_attribute_t* xml_create_attribute(const char *name, const char *value) {
    if (!name) return NULL;
    
    xml_attribute_t *attr = malloc(sizeof(xml_attribute_t));
    if (!attr) return NULL;
    
    attr->name = strdup(name);
    attr->value = value ? strdup(value) : NULL;
    attr->next = NULL;
    
    return attr;
}

// 添加属性到节点
void xml_add_attribute(xml_node_t *node, xml_attribute_t *attr) {
    if (!node || !attr) return;
    
    if (!node->attributes) {
        node->attributes = attr;
    } else {
        xml_attribute_t *current = node->attributes;
        while (current->next) {
            current = current->next;
        }
        current->next = attr;
    }
}

// 添加子节点
void xml_add_child(xml_node_t *parent, xml_node_t *child) {
    if (!parent || !child) return;
    
    child->parent = parent;
    
    if (!parent->children) {
        parent->children = child;
    } else {
        xml_node_t *current = parent->children;
        while (current->next) {
            current = current->next;
        }
        current->next = child;
    }
}

// 释放XML文档
void xml_free_document(xml_document_t *doc) {
    if (!doc) return;
    
    if (doc->root) {
        xml_free_node(doc->root);
    }
    
    free(doc->version);
    free(doc->encoding);
    free(doc);
}

// 释放XML节点
void xml_free_node(xml_node_t *node) {
    if (!node) return;
    
    // 释放子节点
    xml_node_t *child = node->children;
    while (child) {
        xml_node_t *next = child->next;
        xml_free_node(child);
        child = next;
    }
    
    // 释放属性
    xml_attribute_t *attr = node->attributes;
    while (attr) {
        xml_attribute_t *next = attr->next;
        free(attr->name);
        free(attr->value);
        free(attr);
        attr = next;
    }
    
    free(node->name);
    free(node->content);
    free(node);
}

// 查找节点
xml_node_t* xml_find_node(xml_node_t *parent, const char *name) {
    if (!parent || !name) return NULL;
    
    xml_node_t *child = parent->children;
    while (child) {
        if (child->name && strcmp(child->name, name) == 0) {
            return child;
        }
        child = child->next;
    }
    
    return NULL;
}

// 根据属性查找节点
xml_node_t* xml_find_node_by_attribute(xml_node_t *parent, const char *attr_name, const char *attr_value) {
    if (!parent || !attr_name) return NULL;
    
    xml_node_t *child = parent->children;
    while (child) {
        const char *value = xml_get_attribute(child, attr_name);
        if (value && (!attr_value || strcmp(value, attr_value) == 0)) {
            return child;
        }
        child = child->next;
    }
    
    return NULL;
}

// 获取属性值
const char* xml_get_attribute(xml_node_t *node, const char *attr_name) {
    if (!node || !attr_name) return NULL;
    
    xml_attribute_t *attr = node->attributes;
    while (attr) {
        if (attr->name && strcmp(attr->name, attr_name) == 0) {
            return attr->value;
        }
        attr = attr->next;
    }
    
    return NULL;
}

// 获取节点内容
const char* xml_get_node_content(xml_node_t *node) {
    return node ? node->content : NULL;
}

// 打印XML文档
void xml_print_document(xml_document_t *doc, FILE *output) {
    if (!doc || !output) return;
    
    fprintf(output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    
    if (doc->root) {
        xml_print_node(doc->root, output, 0);
    }
}

// 打印XML节点
void xml_print_node(xml_node_t *node, FILE *output, int indent) {
    if (!node || !output) return;
    
    // 打印缩进
    for (int i = 0; i < indent; i++) {
        fprintf(output, "  ");
    }
    
    if (node->type == XML_NODE_ELEMENT) {
        fprintf(output, "<%s", node->name ? node->name : "");
        
        // 打印属性
        xml_attribute_t *attr = node->attributes;
        while (attr) {
            fprintf(output, " %s=\"%s\"", 
                   attr->name ? attr->name : "", 
                   attr->value ? attr->value : "");
            attr = attr->next;
        }
        
        if (!node->children && !node->content) {
            fprintf(output, "/>\n");
        } else {
            fprintf(output, ">");
            
            if (node->content) {
                fprintf(output, "%s", node->content);
            }
            
            if (node->children) {
                fprintf(output, "\n");
                xml_node_t *child = node->children;
                while (child) {
                    xml_print_node(child, output, indent + 1);
                    child = child->next;
                }
                
                for (int i = 0; i < indent; i++) {
                    fprintf(output, "  ");
                }
            }
            
            fprintf(output, "</%s>\n", node->name ? node->name : "");
        }
    } else if (node->type == XML_NODE_COMMENT) {
        fprintf(output, "<!-- %s -->\n", node->content ? node->content : "");
    }
}

// 去除空白字符
char* xml_trim_whitespace(char *str) {
    if (!str) return NULL;
    
    // 去除前导空白
    while (*str && isspace((unsigned char)*str)) str++;
    
    if (*str == '\0') return str;
    
    // 去除尾随空白
    char *end = str + strlen(str) - 1;
    while (end > str && isspace((unsigned char)*end)) end--;
    *(end + 1) = '\0';
    
    return str;
}

// 解码XML实体
char* xml_decode_entities(const char *str) {
    if (!str) return NULL;
    
    // 简单实现，可以扩展
    char *result = strdup(str);
    // TODO: 实现实体解码 &lt; &gt; &amp; &quot; &apos;
    return result;
}

// 验证XML名称
int xml_is_valid_name(const char *name) {
    if (!name || !*name) return 0;
    
    // 简单验证：字母、数字、下划线、连字符
    for (const char *p = name; *p; p++) {
        if (!isalnum(*p) && *p != '_' && *p != '-' && *p != '.') {
            return 0;
        }
    }
    
    return 1;
}